package com.zeyu.framework.core.configuration;

import com.zeyu.framework.core.common.condition.DistributedCondition;
import com.zeyu.framework.core.distributed.ShiroSessionService;

import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 * spring boot 分布式部署,前面实现了一个 nginx + tomcat + redis 的分布式,但是基于web容器
 * 实现分布式session共享,有一些问题,具体看nginx的部署说明
 * 这里使用shiro的session替换掉web容器的session,通过shiro的session共享实现分布式,由于shiro
 * 框架获取 session里面的属性时，每次都去拿取session，一次请求中会有很多次 获取 session 里面的属性，
 * 所以有很多次，这个如果是本地缓存到无所谓，因为本地缓存是直接放置session对象的，但是如果是共享缓存
 * 比如 redis ，每次获取session都要从redis 里面获取然后反序列化,会出现效率问题
 * 这里使用redis作为shiro实现集群会话管理，并可配置ehcache作为进程内缓存，通过redis消息订阅发布实现session缓存统一
 * <p>
 * 1.Servlet容器在用户浏览器首次访问后会产生Session，并将Session的ID保存到Cookie中(浏览器不同key不一定相同)，
 * 同时Shiro会将该Session缓存到Redis中；
 * 2.用户登录认证成功后Shiro会修改Session属性，添加用户认证成功标识，并同步修改Redis中Session；
 * 3.用户发起请求后，Shiro会先判断本地EhCache缓存中是否存在该Session，如果有，直接从本地EhCache缓存中读取，
 * 如果没有再从Redis中读取Session，并在此时判断Session是否认证通过，如果认证通过将该Session缓存到本地EhCache中；
 * 4.如果Session发生改变，或被删除（用户退出登录），先对Redis中Session做相应修改（修改或删除）；
 * 再通过Redis消息通道发布缓存失效消息，通知其它节点EhCache失效
 * Created by zeyuphoenix on 16/7/6.
 */
@Configuration
@Conditional(DistributedCondition.class)      //分布式时候才用,否则不加载configuration的配置
@AutoConfigureBefore(RedisConfiguration.class)
public class DistributedConfiguration {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * shiro的分布式bean管理器,只有在分布式时才可用
     */
    @Bean
    public ShiroSessionService shiroSessionService() {
        return new ShiroSessionService();
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
